package com.example.bluetoothframework.scan

import android.bluetooth.BluetoothAdapter
import android.bluetooth.BluetoothDevice
import android.bluetooth.le.*
import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import android.os.Handler
import android.os.Looper
import android.os.ParcelUuid
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData

data class ScannedDevice(
    val name: String?,
    val address: String,
    val type: DeviceType
)

enum class DeviceType {
    CLASSIC, BLE
}

class ScanModule(private val context: Context) {

    private val bluetoothAdapter: BluetoothAdapter? = BluetoothAdapter.getDefaultAdapter()
    private val bleScanner: BluetoothLeScanner? = bluetoothAdapter?.bluetoothLeScanner

    private val _scannedDevices = MutableLiveData<List<ScannedDevice>>()
    val scannedDevices: LiveData<List<ScannedDevice>> = _scannedDevices

    private val handler = Handler(Looper.getMainLooper())
    private var isScanning = false
    private var scanCallback: ScanCallback? = null
    private val devicesSet = mutableSetOf<String>() // 用于去重
    private val scannedDeviceList = mutableListOf<ScannedDevice>() // 存储扫描结果

    private val pairedDevices: Set<String> by lazy {
        bluetoothAdapter?.bondedDevices?.map { it.address }?.toSet() ?: emptySet()
    }

    private var classicReceiver: BroadcastReceiver? = null

    /**
     * 开始扫描所有蓝牙设备。
     * @param scanDuration 单次扫描持续时间（毫秒），默认为 10 秒
     */
    fun startScan(scanDuration: Long = 10000L) {
        if (bluetoothAdapter == null || !bluetoothAdapter.isEnabled) {
            throw IllegalStateException("蓝牙不可用或未启用。")
        }

        if (isScanning) return

        isScanning = true
        devicesSet.clear()
        scannedDeviceList.clear()
        _scannedDevices.postValue(scannedDeviceList)

        // 开始经典蓝牙扫描
        startClassicScan()

        // 开始 BLE 扫描
        startBleScan()

        // 定时停止扫描
        handler.postDelayed({
            stopScan()
        }, scanDuration)
    }

    /**
     * 停止扫描所有蓝牙设备。
     */
    fun stopScan() {
        if (!isScanning) return

        stopClassicScan()
        stopBleScan()

        isScanning = false
    }

    /**
     * 开始经典蓝牙扫描。
     */
    private fun startClassicScan() {
        if (!bluetoothAdapter!!.isEnabled) return

        bluetoothAdapter.startDiscovery()
        classicReceiver = object : BroadcastReceiver() {
            override fun onReceive(context: Context, intent: Intent) {
                when (intent.action) {
                    BluetoothDevice.ACTION_FOUND -> {
                        val device = intent.getParcelableExtra<BluetoothDevice>(BluetoothDevice.EXTRA_DEVICE)
                        device?.let {
                            val deviceAddress = it.address
                            if (devicesSet.add(deviceAddress) && !pairedDevices.contains(deviceAddress)) { // 过滤已配对设备
                                scannedDeviceList.add(
                                    ScannedDevice(
                                        name = it.name ?: "未知设备",
                                        address = deviceAddress,
                                        type = DeviceType.CLASSIC
                                    )
                                )
                                _scannedDevices.postValue(scannedDeviceList)
                            }
                        }
                    }
                    BluetoothAdapter.ACTION_DISCOVERY_FINISHED -> {
                        stopClassicScan() // 自动停止扫描
                    }
                }
            }
        }
        val filter = IntentFilter(BluetoothDevice.ACTION_FOUND).apply {
            addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
        }
        context.registerReceiver(classicReceiver, filter)
    }

    /**
     * 停止经典蓝牙扫描。
     */
    private fun stopClassicScan() {
        bluetoothAdapter?.cancelDiscovery()
        classicReceiver?.let { context.unregisterReceiver(it) }
        classicReceiver = null
    }

    /**
     * 开始 BLE 扫描。
     */
    private fun startBleScan(serviceUuids: List<ParcelUuid>? = null) {
        if (!bluetoothAdapter!!.isEnabled || bleScanner == null) return

        scanCallback = object : ScanCallback() {
            override fun onScanResult(callbackType: Int, result: ScanResult) {
                val device = result.device
                val deviceAddress = device.address
                if (devicesSet.add(deviceAddress) && !pairedDevices.contains(deviceAddress)) { // 过滤已配对设备
                    scannedDeviceList.add(
                        ScannedDevice(
                            name = device.name ?: "未知设备",
                            address = deviceAddress,
                            type = DeviceType.BLE
                        )
                    )
                    _scannedDevices.postValue(scannedDeviceList)
                }
            }

            override fun onBatchScanResults(results: List<ScanResult>) {
                results.forEach { result ->
                    val device = result.device
                    val deviceAddress = device.address
                    if (devicesSet.add(deviceAddress) && !pairedDevices.contains(deviceAddress)) {
                        scannedDeviceList.add(
                            ScannedDevice(
                                name = device.name ?: "未知设备",
                                address = deviceAddress,
                                type = DeviceType.BLE
                            )
                        )
                    }
                }
                _scannedDevices.postValue(scannedDeviceList)
            }

            override fun onScanFailed(errorCode: Int) {
                isScanning = false
            }
        }

        val scanSettings = ScanSettings.Builder()
            .setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY)
            .build()

        val scanFilters = serviceUuids?.map {
            ScanFilter.Builder().setServiceUuid(it).build()
        } ?: emptyList()

        bleScanner.startScan(scanFilters, scanSettings, scanCallback)
    }

    /**
     * 停止 BLE 扫描。
     */
    private fun stopBleScan() {
        bleScanner?.stopScan(scanCallback)
        scanCallback = null
    }
}
